/*
  Copyright (c) 2010 Les Newell. All rights reserved

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef SERIAL_H_INCLUDED
#define SERIAL_H_INCLUDED

#include "wx/ctb/serport.h"


BEGIN_DECLARE_EVENT_TYPES()
DECLARE_LOCAL_EVENT_TYPE(wxEVT_LIST_RECEIVED, -1)
DECLARE_LOCAL_EVENT_TYPE(wxEVT_LOG, -1)
DECLARE_LOCAL_EVENT_TYPE(wxEVT_CONNECT, -1)
END_DECLARE_EVENT_TYPES()


class wxStringEvent : public wxCommandEvent
{
public:
    wxStringEvent(WXTYPE type = wxEVT_NULL, int id = 0): wxCommandEvent(type,id)
    {
    }
    virtual wxEvent* Clone() const
    {
        return(new wxStringEvent(*this));
    }
    void SetString(const wxString& strg)
    {
        m_string = strg;
    };

    wxString GetString() const
    {
        return(m_string);
    }
protected:
    wxStringEvent(const wxStringEvent& src) : wxCommandEvent(src)
    {
        m_string = src.m_string;
    }
private:
    wxString m_string;;
    DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxStringEvent)
};

class Serial : private wxTimer
{
public:
    Serial(wxEvtHandler * target)
    {
        m_evtTarget = target;
        Start(10);
        m_running = false;
        m_waiting = false;
        m_errorCount = 0;
    }
    ~Serial()
    {
        Close();
    }
    bool IsOpen()
    {
        return(m_port.IsOpen());
    }

    bool ListModules(wxArrayString& result);
    bool WriteEEPROM();
    bool SetValue(const wxString& s);
    bool GetValue(const wxString& name, double & v);
    bool SetValue(const wxString& name, const wxString& value);
    bool Send(const wxString& text, wxString& response, const int timeout = 1000);
    bool Send(const wxString& text, const int timeout = 1000);
    bool RunList(wxArrayString & list);
    bool EnableList(const bool state);
    bool Open();
    void Close();
    void ClearList()
    {
        m_list.Clear();
        EnableList(false);
    }
    bool Ping();
    bool GetVersion(wxString& version);

private:
    bool Send(const wxString& text, wxArrayString& response);
    bool RawSend(const wxString& text, const bool log = true);
    enum SERIAL_RESULT{resNODATA, resERROR, resOK};

    bool ReadUntilEOS(wxString& string);
    virtual void Notify();
    SERIAL_RESULT CheckSerial(wxString * target = NULL);
    bool ReadSerial (wxString& target, const int timeout = 1000);
    void SignalState(bool state);
    bool SendR();

    bool m_running;
    bool m_waiting;
    int m_errorCount;
    wxTimer m_timer;
    wxSerialPort m_port;
    wxEvtHandler * m_evtTarget;
    wxArrayString m_list;
};

#endif

